﻿using DLLPC.Utilities;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using RRQMSocket;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace VisionCore
{
    public class MeasureSensorComHelper
    {
        private SerialPort serialPort = new SerialPort();
        private SafeQueue<byte[]> sq_CMD = new SafeQueue<byte[]>();

        private double msValue1 = 0;
        private double msValue2 = 0;
        private double msValue3 = 0;
        private double msValue4 = 0;

        public MeasureSensorComHelper(string portName,int baudRate = 38400, int dataSize = 8, Parity parity = Parity.None, StopBits stopBits = StopBits.Two)
        {
            serialPort.PortName = portName;
            serialPort.BaudRate = baudRate;
            serialPort.DataBits = dataSize;
            serialPort.Parity = parity;
            serialPort.StopBits = stopBits;
            serialPort.ReadTimeout = 1000;
        }

        public double MsValue1
        {
            get
            {
                return msValue1;
            }
        }
        public double MsValue2
        {
            get
            {
                return msValue2;
            }
        }
        public double MsValue3
        {
            get
            {
                return msValue3;
            }
        }
        public double MsValue4
        {
            get
            {
                return msValue4;
            }
        }
        private bool isRun = true;
        private Thread thread;

        private bool connected = false;
        public bool Connected
        {
            get { return connected; }
        }

        private bool enable = true;
        public bool Enable
        {
            get { return enable; }
        }

        public void Start(bool en = true)
        {
            enable = en;
            thread = new Thread(threadFunction);
            thread.IsBackground = true;
            thread.Start();
        }

        public void Quit()
        {
            Disconnect();
            isRun = false;
        }

        private void threadFunction()
        {
            if (!Enable) return;

            while (isRun)
            {
                pollingFunction();

                SystemTimeCounter.timeBeginPeriod(1);
                Thread.Sleep(1);
                SystemTimeCounter.timeEndPeriod(1);
            }
        }

        int statusCode = 0;
        private void pollingFunction()
        {
            try
            {
                switch (statusCode)
                {
                    case 0:
                        {
                            if (Connect())
                            {
                                statusCode = 10;
                                connected = true;
                                LogMsg("位移传感器 连接成功！");
                            }
                            else
                            {
                                Thread.Sleep(4000);
                            }
                        }
                        break;
                    case 10:
                        {
                            ProcessCmd();
                        }
                        break;
                    case 20:
                        {
                            statusCode = 0;
                            connected = false;
                        }
                        break;
                }
            }
            catch (Exception ex)
            {

                throw;
            }
        }

        private bool Connect()
        {
            try
            {
                serialPort.Open();
            }
            catch (Exception ex)
            {
                return false;
            }

            return true;
        }

        private void Disconnect()
        {
            if (serialPort.IsOpen)
            {
                serialPort.Close();
            }
        }

        private bool blnReadFlag = false;
        private void ProcessCmd()
        {
            while (sq_CMD.Count > 0)
            {
                byte[] cmd = sq_CMD.Dequeue();
                try
                {
                    serialPort.DiscardInBuffer();
                    serialPort.DiscardOutBuffer();
                    serialPort.Write(cmd,0,8);
                    LogMsg("发送命令:至位移传感器");
                }
                catch (Exception ex)
                {

                    throw;
                }

                blnReadFlag = true;

                Thread.Sleep(10);

                if (blnReadFlag)
                {
                    try
                    {
                        if (serialPort.BytesToRead == 8 || serialPort.BytesToRead == 21)
                        {
                            byte[] readBuf = new byte[serialPort.BytesToRead];
                            serialPort.Read(readBuf, 0, readBuf.Length);

                            ushort code = MemoryAccess.GetUshort(readBuf, 0);

                            if (code == 0x8003)
                            {
                                msValue1 = MemoryAccess.GetDouble(readBuf, 3, 3);
                                msValue2 = MemoryAccess.GetDouble(readBuf, 7, 3);
                                msValue3 = MemoryAccess.GetDouble(readBuf, 11, 3);
                                msValue4 = MemoryAccess.GetDouble(readBuf, 15, 3);
                                LogMsg(String.Format("位移传感器read value success:{0},{1},{2}，{3}", msValue1, msValue2, msValue3,msValue4));
                            }
                            else
                            {
                                msValue1 = -1;
                                msValue2 = -1;
                                msValue3 = -1;
                                msValue4 = -1;
                            }

                            if (code == 0x8006)
                            {
                                LogMsg("位移传感器设置零点完成");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogMsg("位移传感器read value error:" + ex.Message);
                        throw;
                    }
                    blnReadFlag = false;
                }

                Thread.Sleep(10);

                if (sq_CMD.Count > 5)
                {
                    sq_CMD.Clear();
                }
            }
        }

        public void SendCommand(byte[] sendbytes)
        {
            sq_CMD.Enqueue(sendbytes);
        }
        public  void SetCommand(CommandType cmd)
        {
            byte[] sendbytes = new byte[8];
            switch (cmd)
            {
                case CommandType.GetValue:
                    sendbytes[0] = 0x80;
                    sendbytes[1] = 0x03;
                    sendbytes[2] = 0x00;
                    sendbytes[3] = 0x00;
                    sendbytes[4] = 0x00;
                    sendbytes[5] = 0x08;
                    sendbytes[6] = 0x5A;
                    sendbytes[7] = 0x1D;
                    SendCommand(sendbytes);
                    break;
                case CommandType.SetZeroBase:
                    sendbytes[0] = 0x80;
                    sendbytes[1] = 0x06;
                    sendbytes[2] = 0x08;
                    sendbytes[3] = 0x00;
                    sendbytes[4] = 0xAB;
                    sendbytes[5] = 0x56;
                    sendbytes[6] = 0x6A;
                    sendbytes[7] = 0xB5;
                    SendCommand(sendbytes);
                    SendCommand(sendbytes);
                    break;
            }
        }
        private void LogMsg(string msg)
        {
            LogHelper.Write(LogHelper.Module.CCD1, msg);
        }
    }

    public enum CommandType
    {
        SetZeroBase,
        GetValue,
    }
}
